package com.jack.blog.config;

import com.jack.blog.cache.monitor.BlogMonitor;
import com.jack.blog.dao.BlogMapper;
import com.jack.blog.dto.BlogDto;
import com.jack.blog.utils.MessageUtil;
import com.jack.blog.utils.PropUtil;
import org.apache.tomcat.dbcp.dbcp.BasicDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * webContainer config
 */
@Configuration
@MapperScan("com.jack.blog.dao")
@ComponentScan({"com.jack.blog.service","com.jack.blog.cache","com.jack.blog.dto", "com.jack.blog.jedis"})
@EnableTransactionManagement
@EnableAspectJAutoProxy
public class ApplicationConfig {

    @Bean
    public DataSource getDataSource(
            @Value("${datasource.driver}")String driver,
            @Value("${datasource.url}")String url,
            @Value("${datasource.username}")String username,
            @Value("${datasource.password}")String password,
            @Value("${datasource.maxActive}")int maxActive,
            @Value("${datasource.minIdle}")int minIdle
    ){
        BasicDataSource mysql = new BasicDataSource();
        mysql.setDriverClassName(driver);
        mysql.setUrl(url);
        mysql.setUsername(username);
        mysql.setPassword(password);
        mysql.setMaxActive(maxActive);
        mysql.setMinIdle(minIdle);
        return mysql;
    }

    /**
     * integrate mybatis
     *
     * @return
     */
    @Bean
    public SqlSessionFactoryBean getSqlSessionFactory(DataSource mysql) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(mysql);
        sqlSessionFactoryBean.setTypeAliasesPackage("com.jack.blog.entity");
        return sqlSessionFactoryBean;
    }

    /**
     * transaction
     */
    @Bean("jdbcTransactionManager")
    public TransactionManager getTransactionManager(DataSource mysql){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(mysql);
        return dataSourceTransactionManager;
    }

    @Bean
    public JedisPool getJedisPool(
            @Value("${redis.host}")String host,
            @Value("${redis.port}")int port,
            @Value("${redis.timing}")int timing,
            @Value("${redis.total}")int total,
            @Value("${redis.maxIdle}")int maxIdle
    ){
        JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxTotal(total);
        JedisPool jedisPool=new JedisPool(jedisPoolConfig,host,port,timing);
        return jedisPool;
    }

    @Bean
    public BlogMonitor getBlogMonitor(JedisPool jedisPool,
                                      BlogMapper blogMapper,
                                      BlogDto blogDto){
        BlogMonitor blogMonitor=new BlogMonitor(jedisPool.getResource(),blogMapper,blogDto);
        Thread thread = new Thread(blogMonitor, "BlogMonitor");
        thread.setDaemon(true);
        thread.start();
        return blogMonitor;
    }

    @Bean
    public PropertySourcesPlaceholderConfigurer getProp()throws Exception{
        PropertySourcesPlaceholderConfigurer configurer=new PropertySourcesPlaceholderConfigurer();
        Properties properties= PropUtil.getConfigProperties("blogConf.properties");
        MessageUtil.setUsername(properties.getProperty("message.username"));
        MessageUtil.setPassword(properties.getProperty("message.password"));
        configurer.setProperties(properties);
        return configurer;
    }
}
